#include <stdio.h>
#include "pli.h"


void dump_node_type(PLI_INT16 node_type)
{
	switch(node_type)
	{
		case tf_null_node:
        io_printf("Not a writable argument.");break;
        case tf_reg_node:
        io_printf("Argument references a reg variable.");break;
        case tf_integer_node:
        io_printf("Argument references an integer variable.");break;
        case tf_real_node:
        io_printf("Argument references a real variable.");break;
        case tf_time_node:
        io_printf("Argument references a time variable.");break;
        case tf_netvector_node:
        io_printf("Argument references a vector net.");break;
        case tf_netscalar_node:
        io_printf("Argument references a scalar net.");break;
        case tf_memory_node:
        io_printf("Argument references a memory.");break;
	}
}

void dump_typep(PLI_INT16 para_type)
{
	switch(para_type)
	{
        case tf_nullparam:
        io_printf("The argument is a null expression (where no text has been given as the argument),.\n");
		io_printf("ornarg is out of range.");
		break;

        case tf_string:
        io_printf("The argument is a literal string.");break;
        case tf_readonly:
        io_printf("The argument is a expression with a value that can be read but not written.");
		break;
        case tf_readwrite:
        io_printf("The argument is a expression with a value that can be read and written.");
		break;
        case tf_readonlyreal:
        io_printf("The argument is a real number expression with a value that can be read but not written.");
		break;
        case tf_readwritereal:
        io_printf("The argument is a real number expression with a value that can be read and written.");
		break;
	}
}

void net_to_mem(s_tfnodeinfo *info,char * buffer,int count)
{
int i, j, index;
int this_bit_a, this_bit_b, ngroups;
char a, b,  *aptr, *bptr;


   //if(info->node_mem_size*info->node_ngroups<count)
	  // count=info->node_mem_size*info->node_ngroups;
   /* assuming sizeof(char) = 1 */

   ngroups = info->node_ngroups;
   io_printf("\n%s:%d,%d,%d\n",__FUNCTION__,ngroups,info->node_mem_size,count);
   for(index=0;index<info->node_mem_size;index++)
   {
	   aptr =  info->node_value.memoryval_p + 2*ngroups*index;
	   bptr =  info->node_value.memoryval_p + 2*ngroups*index + ngroups;

	   for (i=0; i<ngroups; i++) {
		  unsigned char byte;
		  a = aptr[i];
		  b = bptr[i];
		   if(count==0) return;
		   count--;
		  byte=0;
		  for (j=0; j<8; j++) {
			  char bit;

			 this_bit_a = (a & 0x1);
			 this_bit_b = (b & 0x1);

			if((this_bit_a == 0) && (this_bit_b == 0))  bit= 0;
			else if((this_bit_a == 1) && (this_bit_b == 0)) bit=1;
			else
			 {
				 tf_error("\ndon't care bit.");
				 bit=0;
			 }

	                       
			 a >>= 1; b >>= 1;
			 byte>>=1;

			 if(bit==1)byte |=0x80;
		  }
		 *buffer++=byte;
		 count--;

		 if(count==0) return;
	   }
   }
}


void mem_to_net(s_tfnodeinfo *info,char * buffer,int count)
{
int i, j, index;
int   ngroups;
char a,   *aptr, *bptr;

   ngroups = info->node_ngroups;
   //if(info->node_mem_size*info->node_ngroups<count)
	  // count=info->node_mem_size*info->node_ngroups;
   /* assuming sizeof(char) = 1 */

   io_printf("\n%s:%d,%d,%d\n",__FUNCTION__,ngroups,info->node_mem_size,count);
   for(index=0;index<count;index++)
   {
	   aptr =  info->node_value.memoryval_p + 2*ngroups*index;
	   bptr =  info->node_value.memoryval_p + 2*ngroups*index + ngroups;

	   for (i=0; i<ngroups; i++) {
		   unsigned char byte;
	   
		   if(count==0) return;
		   count--;

		   a=1;

		  byte=*buffer++;
		  for (j=0; j<8; j++) {

			  if(byte&a)
			  {
				  aptr[i]|=a;
				  bptr[i]&=~a;
			  }
			  else
			  {
				  aptr[i]&=~a;
				  bptr[i]&=~a;
			  }
			  a<<=1;

		  }

	   }
   }
}

void net_to_mem_be(s_tfnodeinfo *info,char * buffer,char be)
{
int i, j, index;
int this_bit_a, this_bit_b, ngroups;
char a, b,  *aptr, *bptr;
int count=8;

   ngroups = info->node_ngroups;
   if(info->node_mem_size*ngroups<8)
   {
	   io_printf("mismatch.");
   }
   /* assuming sizeof(char) = 1 */

   io_printf("\n%s:%d,%d,%x\n",__FUNCTION__,ngroups,info->node_mem_size,be);
   for(index=0;index<info->node_mem_size ;index++)
   {
	   aptr =  info->node_value.memoryval_p + 2*ngroups*index;
	   bptr =  info->node_value.memoryval_p + 2*ngroups*index + ngroups;



	   for (i=0; i<ngroups; i++,be>>=1) {
		  unsigned char byte;
		  a = aptr[i];
		  b = bptr[i];

		  byte=0;
		  for (j=0; j<8; j++) {
			  char bit;

			 this_bit_a = (a & 0x1);
			 this_bit_b = (b & 0x1);

			if((this_bit_a == 0) && (this_bit_b == 0))  bit= 0;
			else if((this_bit_a == 1) && (this_bit_b == 0)) bit=1;
			else
			 {
				 tf_error("\ndon't care bit.");
				 bit=0;
			 }

	                       
			 a >>= 1; b >>= 1;
			 byte>>=1;

			 if(bit==1)byte |=0x80;
		  }

		   if((be&1)==0)
		   {
		       io_printf("%02x ",byte);
			   *buffer++=byte;
		   }
		   else
			   buffer ++;
		   count --;
		   if(count==0) return;

	   }
   }
}


void mem_to_net_be(s_tfnodeinfo *info,char * buffer,char be)
{
int i, j, index;
int   ngroups;
char a,   *aptr, *bptr;
int count =8;

   ngroups = info->node_ngroups;

   if(info->node_mem_size*ngroups<8)
   {
	   io_printf("mismatch.");
   }
   /* assuming sizeof(char) = 1 */

   io_printf("\n%s:%d,%d,%x\n",__FUNCTION__,ngroups,info->node_mem_size,be);

   for(index=0;index<info->node_mem_size;index++)
   {
	   aptr =  info->node_value.memoryval_p + 2*ngroups*index;
	   bptr =  info->node_value.memoryval_p + 2*ngroups*index + ngroups;

	   for (i=0; i<ngroups; i++) {
		   unsigned char byte;

		   byte=*buffer++;
          if((be&1)==0) 
		  {
			  io_printf("%02x ",byte);
		 	  a=1; 
			  for (j=0; j<8; j++) {

				  if(byte&a)
				  {
					  aptr[i]|=a;
					  bptr[i]&=~a;
				  }
				  else
				  {
					  aptr[i]&=~a;
					  bptr[i]&=~a;
				  }
				  a<<=1;
			  }
		  }
		  count --;
		  be>>=1;

		  if(count==0) return;

	   }
   }
}